查看原文
其他

Python创建可以打开文件的EXE

2017-12-02 王智博 Python爱好者社区

作者:数据取经团——王智博

数据取经团(公众号:zlx19930503)

专注R、Python数据分析挖掘、可视化、机器学习


首先抛出一个要解决的问题,在学python时用jupyter notebook记了很多笔记,而实际操作时有一些细节不记得了,需要查看笔记。但是一个.ipynb文件用文本编辑器打开,多了很多我们不想看到的文本,而用jupyter打开又很慢。于是需要设置出一个可执行程序(exe文件)来打开.ipynb文件。

本文展示了一步步学习如何创建.exe程序的过程,最后做出我们想要的程序

本文分为如下几个内容

  • 生成最简单的exe程序,只打印出一段字符串

  • 带有参数的exe程序

  • 参数是文件名的情况

  • 真正实现

  • 改进方向


生成最简单的exe程序

将python脚本转化为exe程序比较常用的是两个库,py2exe和pyinstaller,由于前者不支持3.5及以上版本,操作也相对复杂,因此这里选择pyinstaller。

安装:在cmd中直接pip install PyInstaller 就安装好了。


之后我们只要使用pyinstaller这条命令即可,正常来说我们安装好这个库之后,pyinstaller.exe就在环境变量中了,所以我们可以在任何文件夹下的cmd窗口中调用这条命令。


pyinstaller库生成exe文件非常简单,只要一条命令就能自动生成,我们来看一下下面这个简单例子

在cmd_try文件夹下创建hello.py文件,文件中的内容如下


i = input("please input your name: ") print("Hello World "+i+"!")
# 注意:py2中的raw_input在py3中改成了input
# 用input而不是只是print是为了防止到时候调用exe程序时窗口一闪而过

然后我们在cmd_try文件夹下打开命令窗口,输入 pyinstaller hello.py 就会自动生成几个文件夹,dist文件夹中的hello文件夹中,就有了hello.exe文件,双击这个文件就会弹出一个让你输入名字的窗口,这就代表这个可执行程序创建完成。 

注:同时会生成一个build文件,其中也有一个hello.exe,不用管它,把build文件夹删掉,dist中的hello.exe文件依然可以运行 


如果要继续修改程序,修改后的hello.py保存后,要再用pyinstaller hello.py这条命令重新生成,覆盖原有的文件,hello.exe才能执行新的功能。


下面我们在命令行中调用这个可执行程序 

在之前的命令行窗口中输入 cd dist 进入dist文件夹中,再输入 cd hello 进入hello文件夹中,再输入两种命令都可以:

  • 直接输入hello即调用了hello.exe文件,会在当前这个命令窗口中让你输入你的名字

  • 输入 start hello 则会另外出现一个命令窗口让你输入你的名字

  • 其中第一种其实和在cmd_try文件夹下的命令行窗口中输入python hello.py效果相同,所以我们可以用这个来测试,测试结束后再生成exe文件


带有参数的exe程序

因为我们的exe程序需要能够打开一个文件,所以需要调用外部参数。下面我们实现在命令行调用hello.py文件时传入参数。这里使用python内置的命令行解析库argparse,这个库的官网特别详细,一步一步教你如何操作,有兴趣的读者可以直接去官网学习,这里仅仅做最简单的使用。


hello.py文件中内容改为

import argparse parser = argparse.ArgumentParser() parser.add_argument("name", help="input your name") # 添加 name 参数,并指定help信息
args = parser.parse_args() # 让args这个变量可以引用这个参数
print("Hello World "+ args.name +"!") # 用args.name引用命令行中输入的参数

我们先直接用python来调用,在cmd_try目录下的cmd窗口输入 python hello.py "bob" ,我们想要的结果就会在下面被打印出来

注:因为刚刚我们用cd命令把命令行窗口的位置切换到了hello文件夹下,如果想返回 cmd_try 文件夹下,则输入两次 cd .. 即可

接下来我们将程序打打包成exe文件,输入pyinstaller hello.py

cd到hello文件夹下输入hello "bob"也可以打印出正常的结果


参数是文件名

为了和我们的目标更接近一点,我们现在实现提取一个txt文件中的内容,前后加一个html的标签,再存成一个html文件

hello.py文件换为如下内容

import argparse parser = argparse.ArgumentParser() parser.add_argument("file", help="input your filename") # 添加 file 参数,并指定help信息
args = parser.parse_args() # 让args这个变量可以引用这个参数
with open(args.file, "r") as f:    r = f.read() html = '<html><body>' + r + '</html></body>'
with open("a.html", "w") as f:    f.write(html)

同时在cmd_try文件夹中创建hi.txt文件,内容如下

Hi world! Hello world!

在cmd_try文件夹下的cmd窗口中输入 python hello.py "hi.txt" 发现执行成功,在cmd_try文件夹下生成了一个a.html文件,我们可以双击这个文件则自动用浏览器打开,内容也是我们刚刚指定的内容。


于是我们再执行pyinstaller hello.py转化为exe程序。同时删除刚刚生成的a.html文件。

在hello文件夹下的cmd窗口中输入 hello C:\python\cmd_try\hi.txt(具体更改为读者电脑中hi.txt文件所在路径) 则会在hello文件夹下生成a.html


删除a.html文件,我们再换一种方式运行

右键hi.txt,选择打开方式-选择其他应用-更多应用-在这台电脑上查找其他应用,然后找到hello.exe的位置,勾选上“始终用此程序打开”,点击打开。这次没反应,但是下次你双击这个文件,就会在cmd_try文件夹下产生一个a.html文件,即运行成功。必须要设置默认用这个程序打开该类型文件,因为用这个过程选打开是没有效果的,只有双击打开才可以。双击打开就相当于用hello.exe调用这个文件作为参数,也就是之前我们在命令行中输入的执行代码。

到现在就万事具备了,接下来我们只要把试验的代码换成处理.ipynb文件的就可以了


真正实现

用文本编辑器打开.ipynb文件发现,它是一个json格式的文本数据,因此我们可以直接读取,转化为字典列表,再进行提取、添加标签即可生成网页源代码,再写出来成一个html文件即可。

因为主要是查看代码,所以这里只提取标题和代码,文本不予提取。标题会汇总在一起放在前面构成目录链接。

在my_project文件夹下建立一个ipynb_view.py文件,里面内容如下

import re
import json
import argparse
def view_ipynb_html(path_ipy, newname): # 传入要打开的文件路径,和新生成的文件名称    # path_ipy 是.ipynb文件及所在路径    with open(path_ipy, 'r', encoding='utf-8') as f:        a = f.read() # 读取得到的是一个json格式的字符串    b = json.loads(a) # 转化为字典格式便于处理    css = '<style type="text/css">\nul li{list-style: none;}\na {text-decoration: none}</style>' # 添加css样式,让目录简单一点    s = '<html>\n' + css + '<body>\n i want to replace here \n' # 创建一个字符串变量,之后所有内容往上面加,组成一个完整的html代码    contents = '<ul>\n' # 目录的html代码,之后替换上面的 i want to replace here    for d in b['cells']:        
       if d['cell_type'] == 'raw' or d['cell_type'] == 'code': # 提取代码            s += '<xmp>' + '\n'  # 这个标签可以把里面的内容原样输出            for i in d['source']:                s += i.rstrip() + '\n'            s += '</xmp><br>\n'        elif d['cell_type'] == 'markdown': # 提取标题            result = re.findall('#+ .+',d['source'][0])            
           if result:                n = result[0].count('#') # 查看几级标题                result1 = re.sub('#+ ','',result[0])                s += '<h' + str(n) + ' id="' + result1 +'">' + result1 + '</h' + str(n) + '>' + '\n'                contents += '<li><a href="#' + result1 + '" target="">' + '&nbsp;'*(n-1)*4 + result1 + '</a></li>\n'    s += '</body>\n</html>'    contents += '</ul>'    s = s.replace('i want to replace here',contents)    
   with open(newname, 'w') as f:        f.write(s)# 命令行解析,以文件及其路径作为文件的参数

parser = argparse.ArgumentParser() parser.add_argument("file", help="input your filename") # 添加 file 参数,并指定help信息
args = parser.parse_args() # 让args这个变量可以引用file这个参数

# 提取新文件名
oriname = re.search("\\\\(\w*?\.ipynb)",args.file).group(1) newname = oriname.replace('ipynb','html')# 调用函数创建文件

view_ipynb_html(args.file,newname)


文件写好保存之后,在ipynb_view文件夹下打开命令行窗口,输入 python ipynb_view.py C:\Jupyter\base.ipynb (路径改为读者自己的.ipynb文件路径),运行之后即可在ipynb文件夹下生成一个base.html文件,可以用浏览器打开查看笔记内容。

下面我们再将py文件转化为可执行程序。在ipynb_view文件夹下打开命令行窗口,输入pyinstaller ipynb_view.py即创建完成。

之后只要找到一个.ipynb文件,设置打开方式默认是ipynb_view.exe,以后每次双击.ipynb文件都会在.ipynb所在文件夹下生成一个同名的.html文件,速度还是很快的,这样查看笔记就方便多了。


改进方向

上面只是提供一个思路和简单的实现,还不是十分完善,感兴趣的读者可以再自己把代码完善起来,可以有以下改进方向作为参考

  • 第一是这样每次生成的一个html文件,都要手动删除。如果可以用程序控制把HTML内容直接用浏览器打开就更好了,或者编写用完自动删除的代码

  • 第二是上面创建html代码的python代码可读性不强,只是因为需求比较简单,暂时应付一下,有更高需求的读者可以试一试编写一个添加标签、属性、css样式的类,让代码结构更加清晰。或者用现成的pyH库貌似可以实现

  • 第三是文本内容没有加进来,因为里面有各种markdown格式标记,不是很好处理,这里就直接舍弃了,有需要的读者可以写程序把文本也读取进来

Python爱好者社区历史文章大合集

Python爱好者社区历史文章列表(每周append更新一次)

福利:文末扫码立刻关注公众号,“Python爱好者社区”,开始学习Python课程:

关注后在公众号内回复“课程”即可获取:

0.小编的Python入门视频课程!!!

1.崔老师爬虫实战案例免费学习视频。

2.丘老师数据科学入门指导免费学习视频。

3.陈老师数据分析报告制作免费学习视频。

4.玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。

5.丘老师Python网络爬虫实战免费学习视频。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存